Skip to content

Fix tsvector columns over JSON-mapped navigations/complex properties - #3893

Merged
roji merged 2 commits into
npgsql:mainfrom
hostage2222:fix_tsvector_over_json
Oct 23, 2026
Merged

roji merged 2 commits into
npgsql:mainfrom
hostage2222:fix_tsvector_over_json

Conversation

@hostage2222

Copy link
Copy Markdown
Contributor

When a property is configured as a generated tsvector column that includes a navigation or complex property mapped to JSON via ToJson(), NpgsqlAnnotationProvider only resolved included names as regular properties, throwing a NullReferenceException instead of finding the underlying JSON container column.

Resolution now also checks navigations and complex properties declared on the same type, resolving them to their JSON container column (including renamed columns) and reporting a clear error for names that don't resolve to a property, navigation, or complex property. Adds unit and functional regression tests covering navigation- and complex-property-based JSON tsvector columns, including renamed and mixed scenarios.

Fixes #3075

Copilot AI review requested due to automatic review settings July 24, 2026 14:59

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes design-time migration generation for generated tsvector columns when included names refer to JSON-mapped owned navigations or JSON-mapped complex properties (ToJson()), avoiding the previous NullReferenceException and adding regression coverage.

Changes:

  • Extend NpgsqlAnnotationProvider tsvector included-name resolution to handle JSON-mapped navigations and complex properties (resolving to the JSON container column).
  • Add a dedicated error string for unresolved included names (property/navigation/complex property).
  • Add unit and functional regression tests for JSON-owned navigation/complex-property tsvector scenarios (including renamed/mixed cases).

Reviewed changes

Copilot reviewed 4 out of 5 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
test/EFCore.PG.Tests/Migrations/NpgsqlAnnotationProviderTest.cs Adds unit tests covering JSON navigation/complex-property included-name resolution and failure modes.
test/EFCore.PG.FunctionalTests/Migrations/MigrationsNpgsqlTest.cs Adds functional migration test asserting SQL for generated tsvector over a JSON-owned navigation column.
src/EFCore.PG/Properties/NpgsqlStrings.resx Introduces a new localized error message for unresolved included names.
src/EFCore.PG/Properties/NpgsqlStrings.Designer.cs Adds the strongly-typed accessor for the new error message resource.
src/EFCore.PG/Metadata/Internal/NpgsqlAnnotationProvider.cs Updates design-time annotation generation to resolve included names via properties, JSON navigations, or JSON complex properties.
Files not reviewed (1)
  • src/EFCore.PG/Properties/NpgsqlStrings.Designer.cs: Generated file
Comments suppressed due to low confidence (1)

src/EFCore.PG/Metadata/Internal/NpgsqlAnnotationProvider.cs:121

  • The error text "Could not find property, navigation or complex property" is also used when the name does resolve to a navigation/complex property but isn't mapped to JSON (i.e. container column name can't be resolved). Consider rewording this message (or adding a separate one) to indicate that the included navigation/complex property must be mapped to a JSON container column via ToJson().
                        ?? throw new InvalidOperationException(
                            NpgsqlStrings.TsVectorIncludedPropertyNotFound(valueGeneratedProperty.DeclaringType.DisplayName(), p2))

Comment thread src/EFCore.PG/Metadata/Internal/NpgsqlAnnotationProvider.cs
Cover generated tsvector columns over renamed JSON complex properties in migration tests, and clarify errors for included members that cannot resolve to a column.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: fc2f0a76-43ac-437e-82a8-d5a42585d238
Copilot AI balanced review requested due to automatic review settings October 23, 2026 16:11

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

The generated-strings method TsVectorIncludedPropertyNotFound declares its parameters out of the file's appearance-order convention, which risks a silent argument swap if the auto-generated file is regenerated.

No open issues 🎉

1 previously missed issue

In code that hasn't changed since last review

Low severity Swap included-member parameter order to match message text

src/​EFCore.PG/​Properties/​NpgsqlStrings.Designer.cs:238

This file is marked // <auto-generated /> and follows a consistent convention where each generated method's parameters are ordered by their first appearance in the message text (e.g. SequenceBadType(property, entityType, propertyType) and IncludePropertyNotFound(entityType, property)). Here the message is Included member '{property}' on '{entityType}' ..., so {property} appears first, yet the method declares (object? entityType, object? property). It currently produces the correct message because the call site passes arguments in the same (reversed) order, but this is fragile: if this file is regenerated from the .resx, the parameters will be reordered to (property, entityType), and the existing call site in NpgsqlAnnotationProvider.cs will then silently pass the entity type and member name in swapped positions. Consider ordering the parameters as (property, entityType) to match the convention and updating the call site accordingly.

1 resolved since last review
1 file not reviewed
  • src/EFCore.PG/Properties/NpgsqlStrings.Designer.cs: Generated file

Review effort: Balanced

@roji roji left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @hostage2222 and sorry it took so long to approve this. I've pushed a couple of very minor fixes and will merge and backport this.

@roji
roji merged commit fc4430e into npgsql:main Oct 23, 2026
10 checks passed
@roji

roji commented Oct 23, 2026

Copy link
Copy Markdown
Member

BTW if you comment on #3075, I can assign you on that issue for credit.

roji added a commit that referenced this pull request Oct 23, 2026
…erties (#4076)

Backport #3893 to hotfix/10.0.4, adapting GetContainerColumnName to the EF10 API.

(cherry picked from commit fc4430e)

Co-authored-by: Vladimir Nosov <151604979+hostage2222@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
roji added a commit that referenced this pull request Oct 23, 2026
Backport of #3893 (fc4430e), adapted to EF9 owned-JSON mapping without complex-JSON APIs.

Co-authored-by: Vladimir Nosov <151604979+hostage2222@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
roji added a commit that referenced this pull request Oct 23, 2026
Backport #3893 (fc4430e), adapting container-column resolution and regression tests for EF8 without complex-JSON mapping support.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

NpgsqlTsVector HasGeneratedTsVectorColumn with Json Columns migration creation fails

3 participants